#include "listwindow.h"
#include "ui_listwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect( ui->treeWidget, SIGNAL(itemDoubleClicked ( QTreeWidgetItem *, int )),
             this, SLOT(processItem( QTreeWidgetItem *, int )));

    statusLabel = new QLabel("");
    statusLabel->setAlignment( Qt::AlignHCenter );
    statusLabel->setMinimumSize( statusLabel->sizeHint() );

    infoLabel = new QLabel;
    infoLabel->setIndent(3);
    statusBar()->addWidget( statusLabel );
    statusBar()->addWidget( infoLabel, 1 );

    QLabel * lab = new QLabel( this );
    lab->setIndent(3);
    lab->setText( "Quick view mode: " );
    ui->toolBar->addWidget( lab );

    // create settings form
    mySettings = new settingsDialog( this );
    fullRootPathShow = false;

    quickViewCombo = new QComboBox( this );
    quickViewCombo->setMinimumWidth( 120 );
    ui->toolBar->addWidget( quickViewCombo );

    redrawQuickViewCombo();
    connect( quickViewCombo, SIGNAL( currentIndexChanged ( int ) ), this,
             SLOT( quickViewComboCurrentChanged() ) );

    QSettings settings("Folder index", "Settings");
    quickViewCombo->setCurrentIndex( quickViewCombo->findText(
                    settings.value("Default mode", "DOS" ).toString(), Qt::MatchExactly ) );
    quickViewComboCurrentChanged();

    moveWindow();
    createActions();

    progress = new myProgressDialog( this, Qt::WindowTitleHint | Qt::WindowSystemMenuHint );
    connect( progress, SIGNAL( cancelCalled() ), this, SLOT( on_cancelThread_clicked() ) );

    processInitialSettings();
}

void MainWindow::moveWindow()
{
    QRect frect = frameGeometry();
    frect.moveCenter(QDesktopWidget().availableGeometry().center());
    move(frect.topLeft());
}

void MainWindow::createActions()
{
    folderMenu = new QMenu( ui->treeWidget );
    fileMenu = new QMenu( ui->treeWidget );

    p_folderOpenAction = new QAction( "Open folder", this );
    p_folderExpandAction = new QAction( "Expand folder", this );
    p_folderCollapseAction = new QAction( "Collapse folder", this );
    p_folderExpandAllAction = new QAction( "Expand all", this );
    p_folderCollapseAllAction = new QAction( "Collapse all", this );

    connect( p_folderOpenAction, SIGNAL(triggered()), this, SLOT( p_folderOpenAction_triggered() ) );
    connect( p_folderExpandAction, SIGNAL(triggered()), this, SLOT( p_folderExpandAction_triggered() ) );
    connect( p_folderCollapseAction, SIGNAL(triggered()), this, SLOT( p_folderCollapseAction_triggered() ) );
    connect( p_folderExpandAllAction, SIGNAL(triggered()), this, SLOT( p_folderExpandAllAction_triggered() ) );
    connect( p_folderCollapseAllAction, SIGNAL(triggered()), this, SLOT( p_folderCollapseAllAction_triggered() ) );

    folderMenu->addAction( p_folderOpenAction );
    folderMenu->addAction( p_folderExpandAction );
    folderMenu->addAction( p_folderCollapseAction );
    folderMenu->addAction( p_folderExpandAllAction );
    folderMenu->addAction( p_folderCollapseAllAction );

    p_fileOpenAction = new QAction( "Open file", this );
    p_fileCopyAction = new QAction( "Copy file", this );
    p_fileDeleteAction = new QAction( "Delete file", this );

    connect( p_fileOpenAction, SIGNAL(triggered()), this, SLOT( p_fileOpenAction_triggered() ) );
    connect( p_fileCopyAction, SIGNAL(triggered()), this, SLOT( p_fileCopyAction_triggered() ) );
    connect( p_fileDeleteAction, SIGNAL(triggered()), this, SLOT( p_fileDeleteAction_triggered() ) );

    fileMenu->addAction( p_fileOpenAction );
    fileMenu->addAction( p_fileCopyAction );
    fileMenu->addAction( p_fileDeleteAction );

    connect( folderMenu, SIGNAL( triggered(QAction*)), this, SLOT (contextMenuRequested(QAction*) ));
}

void MainWindow::processInitialSettings()
{
    QStringList headerTitles;
    headerTitles << "Name";

    if ( mySettings->displayFileExtension() )
    {
        if ( !mySettings->attachToFilename() )
             headerTitles << "File ext";
    }

    if ( mySettings->showFullPath() )
        headerTitles << "Full path";

    if ( mySettings->displayItemType() )
        headerTitles << "Type";

    if ( mySettings->displayFileSize() )
        headerTitles << "Size";

    if ( mySettings->creationDate() )
        headerTitles << "Creation date";
    if ( mySettings->modificationDate() )
        headerTitles << "Modification date";
    if ( mySettings->lastAccessDate() )
        headerTitles << "Last access date";
    if ( mySettings->fileAttributes() )
        headerTitles << "File attr";
    if ( mySettings->owner() )
        headerTitles << "Owner";
    if ( mySettings->md5Hash() )
        headerTitles << "Md5 hash";

    ui->treeWidget->setHeaderLabels (headerTitles);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    event->accept();
}

void MainWindow::open_form( const QString& fileName )
{
    totalItemsCount = 0;
    totalFilesCount = 0;
    totalFoldersCount = 0;
    threadCanceled = false;
    ui->treeWidget->clear();

    setWindowTitle( "Index: Loaded file" );

    open( fileName );

    ui->actionSave->setEnabled( false );
    ui->actionExport->setEnabled( false );
    ui->actionRefresh->setEnabled( false );
    quickViewCombo->setEnabled( false );
}

void MainWindow::run_folder( const QString& path )
{
    totalItemsCount = 0;
    totalFilesCount = 0;
    totalFoldersCount = 0;
    threadCanceled = false;
    ui->treeWidget->clear();

    setWindowTitle( "Index:  " + path );

    ftpMode = false;
    dirMode = true;

    startProcessDirOrDrive( QStringList(path) );
}

void MainWindow::run_ftp( const QString& hostname, const QString& username,
                          const QString& password, const QString& remoteDir )
{
    totalItemsCount = 0;
    totalFilesCount = 0;
    totalFoldersCount = 0;
    threadCanceled = false;
    ui->treeWidget->clear();
    mainFtpInfoList.clear();

    ftpParentItem = 0;

    setWindowTitle( "Index:  " + hostname );

    ftpMode = true;
    dirMode = false;

    ftpInfo* fInfo = new ftpInfo();
    fInfo->hostname = hostname;
    fInfo->username = username;
    fInfo->password = password;
    fInfo->remoteDir = remoteDir;
    mainFtpInfoList.append( fInfo );

    for ( int i = 0; i < mainFtpInfoList.size(); i++ )
    {
        ftpInst * myFtp = new ftpInst(this);
        connect( myFtp, SIGNAL(listDone()), this, SLOT(ftpListDone()) );
        connect( myFtp, SIGNAL(refreshDone(int,int,int)), this, SLOT(ftpRefreshDone(int,int,int)) );
        connect( myFtp, SIGNAL(commandError( QString, QString )),
                 this, SLOT(ftpCommandError( QString, QString )) );

        myFtp->setParentTreeWidgetItem( ftpParentItem );
        myFtp->mainWidget = ui->treeWidget;
        myFtp->mySettings = mySettings;
        myFtp->setInputParameters( mainFtpInfoList.at(i)->hostname,
                                   mainFtpInfoList.at(i)->username,
                                   mainFtpInfoList.at(i)->password,
                                   mainFtpInfoList.at(i)->remoteDir );

        myFtp->connectFtp();
        ftpInstList.append(myFtp);
    }
}

void MainWindow::run_form( QStringList folderList, QList<ftpInfo*> ftpInfoList )
{
    totalItemsCount = 0;
    totalFilesCount = 0;
    totalFoldersCount = 0;
    threadCanceled = false;
    ui->treeWidget->clear();
    ftpItemsList.clear();

    ui->actionTotal_space_used->setEnabled( false );
    ui->actionLargest_files->setEnabled( false );
    ui->actionLargest_folders->setEnabled( false );

    ftpMode = true;
    dirMode = true;

    setWindowTitle( "Index List" );

    mainFtpInfoList = ftpInfoList;
    // process folders
    folders = folderList;
    if ( folderList.size() > 0 )
        startProcessDirOrDrive( folderList );
    else
        threadFinished();
}

// --------------------------------- options ------------------------------------------
bool MainWindow::processSubfolders()
{
    QSettings settings("Folder index", "Settings");
    return settings.value( "prsubfolders", false ).toBool();
}

bool MainWindow::autoExpandFolders()
{
    QSettings settings("Folder index", "Settings");
    return settings.value( "autoexpand", false ).toBool();
}

bool MainWindow::useNativeIcons()
{
    QSettings settings("Folder index", "Settings");
    return settings.value( "nativeI", false ).toBool();
}

// ---------------------------------- FTP sector ------------------------------------------
void MainWindow::processItem( QTreeWidgetItem * item, int )
{
    if ( ftpMode && dirMode )
    {
        if (item->text(30) == "ftp" )
            processFtpNode( item );
        else
            processFolderNode( item );

        return;
    }
    if ( ftpMode )
        processFtpNode( item );
    else
        processFolderNode( item );
}

void MainWindow::processFtpNode( QTreeWidgetItem * item )
{
    if ( !processSubfolders() && item->childCount() == 0 && !item->text(26).isEmpty() )
    {
        for (int i = 0; i < ftpInstList.size(); i++)
        {
            QString host = item->text(26).replace( "//", "--" );
            if ( host.indexOf("/") >= 0 )
            {
                host = host.left( host.indexOf("/") ).replace( "--", "//" );

                if ( ftpInstList.at(i)->matchHost( host ) )
                {
                    ftpInstList.at(i)->setClickedTreeWidgetItem( item );
                    ftpInstList.at(i)->proceedFolder();
                    break;
                }
            }
        }
    }
}

void MainWindow::processFolderNode( QTreeWidgetItem * item )
{
    if ( !processSubfolders() && item->childCount() == 0 && isItemFolder(item) )
    {
        threadCanceled = false;

        statusBar()->showMessage ( "Retriving details.." );
        progress->setStatusText( "Retriving details.." );

        progress->reset();
        progress->show();

        pThread.clear();
        pThread.mainWidget = ui->treeWidget;
        pThread.mySettings = mySettings;
        pThread.appendInfo( item->text(26), item );

        // process folder mode
        pThread.setRunMode( 0 );
        pThread.setFilters( processSubfolders(), useNativeIcons() );
        pThread.start();
    }
}

void MainWindow::ftpListDone()
{
    totalItemsCount = 0;
    totalFilesCount = 0;
    totalFoldersCount = 0;
    QTreeWidgetItemIterator it( ui->treeWidget );
    while (*it)
    {
        if ( (*it)->text(22) == "folder" )
            totalFoldersCount++;
        else
            totalFilesCount++;
        ++it;
    }

    statusLabel->setText( "Processings done.." );
    if ( totalFilesCount != 0 && totalFoldersCount != 0 )
        infoLabel->setText( QString("Total folders - %1;  Total files - %2")
                            .arg(totalFoldersCount).arg(totalFilesCount));

    applyFilters();
    for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
        ui->treeWidget->resizeColumnToContents(i);
}

void MainWindow::ftpRefreshDone( int add, int mod, int del )
{
    added += add;
    modified += mod;
    deleted += del;

    statusLabel->setText( "Refreshing done.." );
    infoLabel->setText( QString( "Deleted - %1, Modified - %2, Added - %3")
                        .arg(deleted)
                        .arg(modified)
                        .arg(added));
    applyFilters();
}

void MainWindow::ftpCommandError( QString errorName, QString errorString )
{
    ftpInst * ftpClass = (ftpInst*)sender();
    if ( ftpClass )
    {
        QMessageBox::critical( this, errorName, errorString );
        if ( errorName != "List" )
        {
            for (int i = 0; i < ftpInstList.size(); i++)
            {
                if ( ftpInstList.at(i) == ftpClass )
                    ftpInstList.removeAt(i);
            }
            if ( ftpInstList.size() == 0 )
            {
                this->close();
            }
        }
    }
}

// --------------------------------------------- Thread sector ------------------------------------------------
void MainWindow::threadFinished()
{
    if ( folders.size() == 0 && mainFtpInfoList.size() == 0 )
    {
        totalItemsCount   = pThread.t_totalItemsCount;
        totalFilesCount   = pThread.t_totalFilesCount;
        totalFoldersCount = pThread.t_totalFoldersCount;

        if ( processSubfolders() && autoExpandFolders() )
        {
            QTreeWidgetItemIterator it( ui->treeWidget, QTreeWidgetItemIterator::HasChildren );
            while (*it)
            {
                (*it)->setExpanded( true );
                ++it;
            }
        }

        progress->setValue( progress->maximum() );

        statusBar()->clearMessage();
        if ( !threadCanceled )
        {
            statusLabel->setText( "Processings done.." );
            if ( totalFilesCount != 0 && totalFoldersCount != 0 )
                infoLabel->setText( QString("Total folders - %1;  Total files - %2")
                                    .arg(totalFoldersCount).arg(totalFilesCount));
        }
        else
        {
            threadCanceled = false;
            statusLabel->setText( "Processings cancelled.." );
        }

        applyFilters();
        for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
            ui->treeWidget->resizeColumnToContents(i);
    }
    else
    {
        totalItemsCount   = pThread.t_totalItemsCount;
        totalFilesCount   = pThread.t_totalFilesCount;
        totalFoldersCount = pThread.t_totalFoldersCount;

        if ( processSubfolders() && autoExpandFolders() )
        {
            QTreeWidgetItemIterator it( ui->treeWidget, QTreeWidgetItemIterator::HasChildren );
            while (*it)
            {
                (*it)->setExpanded( true );
                ++it;
            }
        }

        progress->setValue( progress->maximum() );

        statusBar()->clearMessage();
        if ( !threadCanceled )
        {
            statusLabel->setText( "Processings done.." );
            if ( totalFilesCount != 0 && totalFoldersCount != 0 )
                infoLabel->setText( QString("Total folders - %1;  Total files - %2")
                                    .arg(totalFoldersCount).arg(totalFilesCount));
        }
        else
        {
            threadCanceled = false;
            statusLabel->setText( "Processings cancelled.." );
            return;
        }

        for ( int i = 0; i < mainFtpInfoList.size(); i++ )
        {
            ftpParentItem = new QTreeWidgetItem( ui->treeWidget, 0 );
            ftpParentItem->setText( 0, mainFtpInfoList.at(i)->hostname );
            ftpParentItem->setText( 30, "ftp" );
            QPixmap pixmap( ":/images/folder.png" );
            ftpParentItem->setIcon ( 0, pixmap );

            if ( autoExpandFolders() )
                ftpParentItem->setExpanded( true );

            ftpInst * myFtp = new ftpInst(this);
            connect( myFtp, SIGNAL(listDone()), this, SLOT(ftpListDone()) );
            connect( myFtp, SIGNAL(refreshDone(int,int,int)), this, SLOT(ftpRefreshDone(int,int,int)) );
            connect( myFtp, SIGNAL(commandError( QString, QString )),
                     this, SLOT(ftpCommandError( QString, QString )) );

            myFtp->setParentTreeWidgetItem( ftpParentItem );
            myFtp->mainWidget = ui->treeWidget;
            myFtp->mySettings = mySettings;
            myFtp->setInputParameters( mainFtpInfoList.at(i)->hostname,
                                       mainFtpInfoList.at(i)->username,
                                       mainFtpInfoList.at(i)->password,
                                       mainFtpInfoList.at(i)->remoteDir );

            myFtp->connectFtp();
            ftpInstList.append(myFtp);
        }
    }
}

void MainWindow::applySettingsFinished()
{
    if ( processSubfolders() && autoExpandFolders() )
    {
        QTreeWidgetItemIterator it( ui->treeWidget, QTreeWidgetItemIterator::HasChildren );
        while (*it)
        {
            (*it)->setExpanded( true );
            ++it;
        }
    }
    progress->setValue( progress->maximum() );
    statusLabel->setText( "Processings done.." );

    for ( int i = 0; i < mainFtpInfoList.size(); i++ )
    {
        for (int i = 0; i < ftpInstList.size(); i++)
        {
            ftpInstList.at(i)->mySettings = mySettings;
            ftpInstList.at(i)->settingsChanged();
        }
    }
    applyFilters();
    for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
        ui->treeWidget->resizeColumnToContents(i);
}

void MainWindow::on_cancelThread_clicked()
{
    if ( pThread.isRunning() )
    {
        threadCanceled = true;
        pThread.terminate();
        pThread.wait();
    }
    for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
        ui->treeWidget->resizeColumnToContents(i);
}

void MainWindow::processStep( double _step )
{
    int absValue = (int)_step/totalItemsCount*100;
    progress->setValue( absValue );
}

void MainWindow::t_calculateFinished()
{
    totalItemsCount =  pThread.t_totalItemsCount;
    progress->setStatusText("Processings folders..");
    statusBar()->showMessage ( "Processings folders.." );
}

void MainWindow::setFullRootPathShow( bool fp )
{
    fullRootPathShow = fp;
}

void MainWindow::startProcessDirOrDrive( QStringList dirList )
{
    totalItemsCount = 0;
    totalFilesCount = 0;
    totalFoldersCount = 0;

    statusBar()->showMessage ( "Retriving details.." );
    progress->setStatusText( "Retriving details.." );

    progress->reset();
    progress->show();

    pThread.clear();
    pThread.mainWidget = ui->treeWidget;
    pThread.mySettings = mySettings;
    for ( int i = 0; i < dirList.size(); i++ )
    {
        // add main item ( root folder )
        if ( (mySettings->rootFolderShow() || fullRootPathShow) || (ftpMode && dirMode) )
        {
            QTreeWidgetItem * rootItem = new QTreeWidgetItem( ui->treeWidget, 0 );
            rootItem->setText( 0, dirList.at(i) );
            QPixmap pixmap( ":/images/folder.png" );
            rootItem->setIcon ( 0, pixmap );
            if ( mySettings->fullRootPathShow() )
                rootItem->setText( 0, QFileInfo( dirList.at(i) ).absoluteFilePath() );

            pThread.appendInfo( dirList.at(i), rootItem );
        }
        else
            pThread.appendInfo( dirList.at(i), 0 );
    }

    disconnect( &pThread, SIGNAL( finished() ), 0, 0 );
    connect( &pThread, SIGNAL( finished() ), this, SLOT( threadFinished() ) );
    connect( &pThread, SIGNAL( calculateFinished() ), this, SLOT( t_calculateFinished() ) );
    connect( &pThread, SIGNAL( makeStep( double ) ), this, SLOT( processStep( double ) ) );

    // process folder mode
    pThread.setRunMode( 0 );
    pThread.setFilters( processSubfolders(), useNativeIcons() );
    pThread.start();
}

void MainWindow::t_refreshFinished()
{
    if ( ftpMode && dirMode )
    {
        if ( autoExpandFolders() )
        {
            QTreeWidgetItemIterator it( ui->treeWidget, QTreeWidgetItemIterator::HasChildren );
            while (*it)
            {
                (*it)->setExpanded( true );
                ++it;
            }
        }

        progress->setValue( progress->maximum() );
        statusBar()->clearMessage();
        if ( !threadCanceled )
        {
            deleted  += pThread.deleted >=0  ?  pThread.deleted : 0;
            modified += pThread.modified >=0 ?  pThread.modified : 0;
            added    += pThread.added >=0    ?  pThread.added : 0;

            statusLabel->setText( "Refreshing done.." );
            infoLabel->setText( QString( "Deleted - %1, Modified - %2, Added - %3")
                                .arg(deleted)
                                .arg(modified)
                                .arg(added));

            for (int i = 0; i < ftpInstList.size(); i++)
                ftpInstList.at(i)->refresh();
            return;
        }
        else
        {
            threadCanceled = false;
            statusLabel->setText( "Refreshing cancelled.." );
        }
        applyFilters();
    } 
    else if ( dirMode )
    {
        if ( autoExpandFolders() )
        {
            QTreeWidgetItemIterator it( ui->treeWidget, QTreeWidgetItemIterator::HasChildren );
            while (*it)
            {
                (*it)->setExpanded( true );
                ++it;
            }
        }

        for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
            ui->treeWidget->resizeColumnToContents(i);

        progress->setValue( progress->maximum() );

        statusBar()->clearMessage();
        if ( !threadCanceled )
        {
            statusLabel->setText( "Refreshing done.." );
            infoLabel->setText( QString( "Deleted - %1, Modified - %2, Added - %3")
                                .arg(pThread.deleted)
                                .arg(pThread.modified)
                                .arg(pThread.added));
        }
        else
        {
            threadCanceled = false;
            statusLabel->setText( "Refreshing cancelled.." );
        }
        applyFilters();
    }
}

void MainWindow::on_actionRefresh_triggered()
{
    deleted = 0;
    modified = 0;
    added = 0;

    // set text color to default
    QTreeWidgetItemIterator iter1( ui->treeWidget );
    while (*iter1)
    {
        (*iter1)->setText( 27, "" );
        if ( (*iter1)->foreground(0) != QBrush( QColor(0, 0, 0) ) )
        {
            for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
            {
                (*iter1)->setForeground( i, QBrush( QColor(0, 0, 0) ) );
                QFont font = (*iter1)->font(0);
                font.setBold( false );
                (*iter1)->setFont( i, font );
            }
        }
        ++iter1;
    }
    ui->treeWidget->clearSelection();

    if ( ftpMode && dirMode )
    {
        statusBar()->showMessage ( "Retriving details.." );
        progress->setStatusText( "Retriving details.." );

        if ( folders.size() > 0 )
        {
            progress->reset();
            progress->show();

            disconnect( &pThread, SIGNAL( finished() ), 0, 0 );
            connect( &pThread, SIGNAL( finished() ), this, SLOT( t_refreshFinished() ) );

            // refresh folder mode
            pThread.setRunMode( 1 );
            pThread.start();
        }
        else
            t_refreshFinished();
    }
    else if ( dirMode )
    {
        statusBar()->showMessage ( "Retriving details.." );
        progress->setStatusText( "Retriving details.." );

        progress->reset();
        progress->show();

        disconnect( &pThread, SIGNAL( finished() ), 0, 0 );
        connect   ( &pThread, SIGNAL( finished() ), this, SLOT( t_refreshFinished() ) );

        // refresh folder mode
        pThread.setRunMode( 1 );
        pThread.start();
    }
    else if ( ftpMode )
    {
        for (int i = 0; i < ftpInstList.size(); i++)
            ftpInstList.at(i)->refresh();
    }
}
// --------------------------------------------------------------------------------------------------------------
void MainWindow::drawTreeItem( QTreeWidgetItem * item, bool isFolder,
                               const QFileInfo &fInfo, const QUrlInfo &urlInfo,
                               int mode )
{
    if ( mode == 1 )
    {
        int col = -1;
        QString dispFileName = fInfo.completeBaseName();
        item->setData( 0, Qt::DisplayRole, dispFileName );
        // 8.3 name format
        item->setData( 20, Qt::DisplayRole, dispFileName );

        // set Icons
        if ( useNativeIcons() )
        {
            QFileIconProvider myIPro;
            QIcon icon = myIPro.icon(fInfo);
            item->setIcon ( 0, icon.pixmap(16) );
        }
        else
        {
            QPixmap pixmap( isFolder ? ":/images/folder.png" : ":/images/file.png");
            item->setIcon ( 0, pixmap );
        }

        col = customColumnNumber( "Type" );
        if ( !isFolder )
        {
            if ( col != -1 )
                item->setData( col, Qt::DisplayRole, "file" );
            item->setData( 22, Qt::DisplayRole, "file" );
        }
        else
        {
            if ( col != -1 )
                item->setData( col, Qt::DisplayRole, "folder" );
            item->setData( 22, Qt::DisplayRole, "folder" );
        }

        col = customColumnNumber( "Full path" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole,
                           QDir::toNativeSeparators( fInfo.absoluteFilePath())
                           .replace( QDir::separator(), mySettings->getSeparator() ) );

        col = customColumnNumber( "Creation date" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole,
                           fInfo.created().toString( mySettings->getDateFormat() + " " + mySettings->getTimeFormat() ));

        col = customColumnNumber( "Modification date" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole,
                           fInfo.lastModified().toString( mySettings->getDateFormat() + " " + mySettings->getTimeFormat() ));

        col = customColumnNumber( "Last access date" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole,
                           fInfo.lastRead().toString( mySettings->getDateFormat() + " " + mySettings->getTimeFormat() ));


        col = customColumnNumber( "Owner" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole, fInfo.owner() );

        item->setData( 26, Qt::DisplayRole, fInfo.absoluteFilePath() );
        item->setData( 29, Qt::DisplayRole, fInfo.lastModified().toString( Qt::ISODate ) );
        item->setText( 30, "folder" );
    }
    if ( mode == 2 )
    {
        int col = -1;
        QString dispFileName = urlInfo.name().left( urlInfo.name().lastIndexOf('.') );
        if ( mySettings->displayFileExtension() )
        {
            if ( mySettings->attachToFilename() )
                dispFileName = urlInfo.name();
            else if ( !isFolder )
            {
                col = customColumnNumber( "File ext" );
                if ( col != -1 )
                {
                    int extLen = urlInfo.name().length() - urlInfo.name().lastIndexOf('.') - 1;
                    item->setData( col, Qt::DisplayRole,
                                   urlInfo.name().right( extLen ));
                }
            }
        }
        item->setText( 0, dispFileName );
        //8.3 name format
        if ( !isFolder )
        {
            item->setData( 20, Qt::DisplayRole,
                           urlInfo.name().left( urlInfo.name().lastIndexOf('.') ).left(8) + "." + urlInfo.name().right( urlInfo.name().lastIndexOf('.')).left(3) );
        }
        else
            item->setData( 20, Qt::DisplayRole, dispFileName );

        QPixmap pixmap( isFolder ? ":/images/folder.png" : ":/images/file.png");
        item->setIcon ( 0, pixmap );

        col = customColumnNumber( "Type" );
        if ( !isFolder )
        {
            if ( col != -1 )
                item->setData( col, Qt::DisplayRole, "file" );
            item->setData( 22, Qt::DisplayRole, "file" );
        }
        else
        {
            if ( col != -1 )
                item->setData( col, Qt::DisplayRole, "folder" );
            item->setData( 22, Qt::DisplayRole, "folder" );
        }

        //col = customColumnNumber( "Full path" );
        //if ( col != -1 )
            //item->setData( col, Qt::DisplayRole, getFullUrlPath( item ) );

        if ( !isFolder )
        {
            col = customColumnNumber( "Size" );
            if ( col != -1 )
                item->setData( col, Qt::DisplayRole, getConvertedSize( urlInfo.size() ) );
        }

        col = customColumnNumber( "Creation date" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole, "" );

        col = customColumnNumber( "Modification date" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole, urlInfo.lastModified().toString( mySettings->getDateFormat() + " " + mySettings->getTimeFormat() ));

        col = customColumnNumber( "Last access date" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole, urlInfo.lastRead().toString( mySettings->getDateFormat() + " " + mySettings->getTimeFormat() ));

        col = customColumnNumber( "File attr" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole, getUrlAttr( urlInfo ) );

        col = customColumnNumber( "Owner" );
        if ( col != -1 )
            item->setData( col, Qt::DisplayRole, urlInfo.owner() );

        item->setData( 23, Qt::DisplayRole, QString::number(urlInfo.size()) );
        //item->setData( 26, Qt::DisplayRole, getFullUrlPath( item ) );
        item->setData( 29, Qt::DisplayRole, urlInfo.lastModified().toString( Qt::ISODate ) );
        item->setText( 30, "ftp" );
    }
}

int MainWindow::customColumnNumber( const QString& name )
{
    int resCol = -1;
    for (int i = 0; i < ui->treeWidget->columnCount(); i++ )
    {
        if ( ui->treeWidget->headerItem()->text(i).left( name.length() ) == name )
        {
            resCol = i;
            break;
        }
    }
    return resCol;
}

QString MainWindow::getConvertedSize( qint64 _size )
{
    if ( mySettings->displayFileSizeType() != 5 )
    {
        double ret = _size;
        for ( int it = 1; it < mySettings->displayFileSizeType(); it++ )
            ret = ret / 1024;

        QString suff;
        switch ( mySettings->displayFileSizeType() )
        {
        case 1:
            {
                suff = " bytes";
                break;
            }
        case 2:
            {
                suff = " kb";
                break;
            }
        case 3:
            {
                suff = " Mb";
                break;
            }
        case 4:
            {
                suff = " Gb";
                break;
            }
        }

        QString retStr = QString::number( ret, 'f', 2 );
        retStr.replace( retStr.mid( retStr.length()-3, 1 ), mySettings->getFractionDel() );

        int _count = (retStr.length()-3)/3+1;
        if ( _count == (retStr.length()-3)/3 )
            _count--;
        for (int i = 1; i < _count; i++)
            retStr.insert( (retStr.length()-3)-(3*i)-(i-1), mySettings->getGroupSeparator() );
        retStr += suff;
        retStr = retStr.simplified();
        if ( retStr.left(1) == mySettings->getGroupSeparator() )
            retStr.remove(0,1);
        return retStr;
    }
    else
    {
        double bytesCount = _size;

        int degree = -1;
        QString degreeStr = " bytes";
        while ( bytesCount >= 1 )
        {
            bytesCount = bytesCount / 1024.0;
            degree++;
        }

        bytesCount *= 1024.0;
        switch ( degree )
        {
        case 1:
            {
                degreeStr = " kb";
                break;
            }
        case 2:
            {
                degreeStr = " Mb";
                break;
            }
        case 3:
            {
                degreeStr = " Gb";
                break;
            }
        }
        QString retStr = QString::number( bytesCount, 'f', 2 );
        retStr.replace( retStr.mid( retStr.length()-3, 1 ), mySettings->getFractionDel() );

        int _count = (retStr.length()-3)/3+1;
        if ( _count == (retStr.length()-3)/3 )
            _count--;
        for (int i = 1; i < _count; i++)
            retStr.insert( (retStr.length()-3)-(3*i)-(i-1), mySettings->getGroupSeparator() );
        retStr += degreeStr;
        retStr = retStr.simplified();
        if ( retStr.left(1) == mySettings->getGroupSeparator() )
            retStr.remove(0,1);
        return retStr;
    }

    return QString::null;
}

QString MainWindow::getUrlAttr( const QUrlInfo &urlInfo )
{
    QString retStr;
    if ( urlInfo.isSymLink() )
        retStr += "System";
    if ( !urlInfo.isWritable() )
    {
        if ( !retStr.isEmpty() )
            retStr += "; ";
        retStr += "Read only";
    }
    return retStr;
}

QString MainWindow::getMd5Hash( const QString& name )
{
    QFile prFile(name);
    if ( !prFile.open( QIODevice::ReadOnly ) )
        return QString::null;

    QByteArray md5data = QCryptographicHash::hash(prFile.readAll(), QCryptographicHash::Md5);
    prFile.close();

    return QString(md5data.toHex() );
}

void MainWindow::on_actionSave_triggered()
{
    QString fileName = QFileDialog::getSaveFileName(this,
                                                    tr("Save File"),
                                                    mySettings->getLastSaveFolder(),
                                                    tr("Listing (*.findex)"));
    saveToFile( fileName );
}

void MainWindow::on_actionExport_triggered()
{
    mainForm expForm( this );
    expForm.setTreeWidget( ui->treeWidget );
    expForm.exec();
}

// --------------------------------- export sector ----------------------------------------
void MainWindow::saveToFile( QString& fileName )
{
    if ( !fileName.isEmpty() )
    {
        mySettings->setLastSaveFolder( fileName.left(fileName.lastIndexOf('/') ) );

        if ( fileName.right(6) == "findex" )
            save( fileName );
    }
}

void MainWindow::save( const QString &_fileName )
{
    QFile file(_fileName);
    if (!file.open(QIODevice::WriteOnly))
        return;

    QDataStream out(&file);
    QStringList fileArray;
    fileArray.append( QString("Listing creator v. 1.0") );
    fileArray.append( QDate::currentDate().toString("dd.MM.yyyy") );

    QString line;
    for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
        line.append( ui->treeWidget->headerItem()->text(i) + "\t" );
    line.append( "type\t" ); // file|folder type
    line.append( "size" ); // file|folder type

    fileArray.append( line );

    QString indentStr;
    for ( int i = 1; i < 5; i++ )
        indentStr += " ";

    QTreeWidgetItemIterator it( ui->treeWidget );
    while (*it)
    {
        line.clear();
        int spaceNum = getParentCount( *it );
        // make indent in begining
        for ( int i = 0; i < spaceNum; i++ )
            line.append( indentStr );

        for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
        {
            line.append( (*it)->text(i) );
            line.append( '\t' );
        }
        line.append( (*it)->text(22) ); // file|folder
        line.append( '\t' );
        line.append( (*it)->text(23) ); // size
        fileArray.append(line);
        ++it;
    }
    out << fileArray;

    file.close();
}

int MainWindow::getParentCount( QTreeWidgetItem * itt )
{
    int result = 0;
    QTreeWidgetItem * temp = itt;
    while ( temp->parent() )
    {
        result++;
        temp = temp->parent();
    }

    return result;
}

bool MainWindow::isItemFolder( QTreeWidgetItem * item )
{
    if ( item->text(22) == "folder" )
        return true;
    return false;
}

// --------------------------------- import sector ----------------------------------------
void MainWindow::on_actionInternalOpen_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open file"),
                                                    mySettings->getLastReadFolder(),
                                                    tr("Listing files (*.findex)"));
    if ( !fileName.isEmpty() )
    {
        mySettings->setLastReadFolder( fileName.left(fileName.lastIndexOf('/') ) );

        if ( fileName.right(6) == "findex" )
            open( fileName );

        ui->actionSave->setEnabled( false );
        ui->actionExport->setEnabled( false );
        ui->actionRefresh->setEnabled( false );
    }
}

void MainWindow::setIconsOnLoad()
{
    QTreeWidgetItemIterator it( ui->treeWidget );
    while (*it)
    {
        QPixmap pixmap( isItemFolder(*it) ? ":/images/folder.png" : ":/images/file.png");
        (*it)->setIcon ( 0, pixmap );

        if ( processSubfolders() && autoExpandFolders() )
            (*it)->setExpanded( isItemFolder(*it) );

        ++it;
    }
}

void MainWindow::open( const QString &_fileName )
{
    QFile file(_fileName);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;
// ============================================================================================================
    QDataStream in(&file);
    QStringList fileList;
    in >> fileList;

    if ( fileList.at(0) != "Listing creator v. 1.0" )
    {
        QMessageBox::critical( this,
                               "Error",
                               "Chosen file has insupported format" );
        return;
    }

    QString headers1 = fileList.at(2);
    QStringList headerNameList = headers1.split('\t', QString::SkipEmptyParts );
    QStringList temp(headerNameList);
    temp.removeLast(); // remove Type and Size
    temp.removeLast();

    ui->treeWidget->setColumnCount(0);
    ui->treeWidget->setHeaderLabels( temp );

    QList<QTreeWidgetItem*> parentItemList;
    QList<int> indentationList;
    parentItemList << ui->treeWidget->invisibleRootItem();
    indentationList << 0;

    // #3
    for ( int i = 3; i < fileList.size(); i++ )
    {
        QString line = fileList.at(i);
        int position = 0;
        while (position < line.length())
        {
            if (line.mid(position, 1) != " ")
                break;
            position++;
        }

        if (position > indentationList.last())
        {
            if (parentItemList.last()->childCount() > 0)
            {
                parentItemList << parentItemList.last()->child(parentItemList.last()->childCount()-1);
                indentationList << position;
            }
        }
        else
        {
            while (position < indentationList.last() && parentItemList.count() > 0)
            {
                parentItemList.pop_back();
                indentationList.pop_back();
            }
        }

        QTreeWidgetItem * itt = new QTreeWidgetItem( parentItemList.last() );
        QStringList tempList = line.split('\t', QString::KeepEmptyParts );
        for (int i = 0; i < headerNameList.count()-1; i++ )
        {
            int col = customColumnNumber( headerNameList.at(i) );
            itt->setData( col, Qt::DisplayRole, tempList.at(i).simplified() );
        }
        itt->setText( 22, tempList.at(headerNameList.count()-2).simplified() );
        itt->setText( 23, tempList.at(headerNameList.count()-1).simplified() );

        parentItemList.last()->addChild(itt);
    }

    file.close();
    setIconsOnLoad();
}

// ---------------------------------- some actions -------------------------------------
void MainWindow::settingsChanged()
{
    ui->treeWidget->setColumnCount(0);
    processInitialSettings();

    if ( ui->treeWidget->topLevelItemCount() > 0 )
    {
        statusBar()->showMessage ( "Retriving details.." );
        progress->setStatusText( "Retriving details.." );

        progress->reset();
        progress->show();
        if ( folders.size() > 0 || mainFtpInfoList.size() > 0 )
        {
            disconnect( &pThread, SIGNAL( finished() ), 0, 0 );
            connect( &pThread, SIGNAL( finished() ), this, SLOT( applySettingsFinished() ) );
        }
        else
        {
            disconnect( &pThread, SIGNAL( finished() ), 0, 0 );
            connect( &pThread, SIGNAL( finished() ), this, SLOT( threadFinished() ) );
        }

        if ( folders.size() > 0 || (folders.size() == 0 && mainFtpInfoList.size() == 0) )
        {
            pThread.setRunMode( 2 );
            pThread.start();
        }
        else
            applySettingsFinished();
    }
}

void MainWindow::quickViewComboCurrentChanged()
{
    if ( !quickViewCombo->currentText().isEmpty() )
    {
        mySettings->getSettings( quickViewCombo->currentText() );
        settingsChanged();
    }
}

void MainWindow::redrawQuickViewCombo()
{
    QSettings settings("Folder index", "Settings");
    QStringList modes = settings.value("Modes", "" ).toString().split( ";", QString::SkipEmptyParts );
    quickViewCombo->addItems( modes );
}

// ----------------------------------- reports -----------------------------------------
void MainWindow::on_actionTotal_files_triggered()
{
    if ( ui->treeWidget->topLevelItemCount() > 0)
    {
        int filesCount = 0;
        QTreeWidgetItemIterator it( ui->treeWidget );
        while (*it)
        {
            //custom column for item type (folder or file)
            if ( (*it)->text(22) == "file" )
                filesCount++;
            ++it;
        }

        QMessageBox::information( this, "Report", "Total files: " + QString::number(filesCount) );
    }
    else
        QMessageBox::critical( this, "Error", "There is nothing to count");
}

void MainWindow::on_actionTotal_folders_triggered()
{
    if ( ui->treeWidget->topLevelItemCount() > 0)
    {
        int foldersCount = 0;
        QTreeWidgetItemIterator it( ui->treeWidget );
        while (*it)
        {
            QTreeWidgetItem * item = *it;
            //custom column for item type (folder or file)
            if ( item->text(22) == "folder" )
                foldersCount++;
            ++it;
        }

        QMessageBox::information( this, "Report", "Total folders: " + QString::number(foldersCount) );
    }
    else
        QMessageBox::critical( this, "Error", "There is nothing to count");
}

void MainWindow::on_actionTotal_space_used_triggered()
{
    if ( ui->treeWidget->topLevelItemCount() > 0)
    {
        double bytesCount = 0;
        QTreeWidgetItemIterator it( ui->treeWidget );
        while (*it)
        {
            QTreeWidgetItem * item = *it;
            if ( item->text(22) == "file" )
            {
                //custom column for item size
                bytesCount += item->text(23).toFloat();             // returns 1234.56
            }
            ++it;
        }

        int degree = -1;
        QString degreeStr = " b";
        while ( bytesCount >= 1 )
        {
            bytesCount = bytesCount / 1024.0;
            degree++;
        }

        bytesCount *= 1024.0;
        switch ( degree )
        {
        case 1:
            {
                degreeStr = " kb";
                break;
            }
        case 2:
            {
                degreeStr = " Mb";
                break;
            }
        case 3:
            {
                degreeStr = " Gb";
                break;
            }
        }

        QMessageBox::information( this, "Report", "Total space used: " + QString::number(bytesCount, 'f', 2) + degreeStr );
    }
    else
        QMessageBox::critical( this, "Error", "There is nothing to count");
}

void MainWindow::on_actionLargest_files_triggered()
{
    int filesCount = 0;
    bool ok = false;
    QList<qlonglong> fileSizeList;
    QList<QTreeWidgetItem *> itemList;

    QTreeWidgetItemIterator it( ui->treeWidget );
    while (*it)
    {
        if ( (*it)->text(22) == "file" )
        {
            filesCount++;
            qlonglong num = (*it)->text(23).toLongLong( &ok, 10 );
            if ( ok && !fileSizeList.contains(num) )
                fileSizeList << num;
        }
        ++it;
    }

    if ( filesCount > 0)
    {
        int number = QInputDialog::getInt(this, tr("Please specify the number of files to display"),
                                          tr("Number:"), 10, 0, filesCount, 1, &ok);

        if ( ok && number > 0 )
        {
            // sorting
            qSort(fileSizeList.begin(), fileSizeList.end());

            for ( int i = 0; i < ( number > fileSizeList.size() ? fileSizeList.size() : number ); i++ )
                itemList.append( findMyFileItems(fileSizeList.at(i)) );

            reportDialog rDlg(this);
            rDlg.setData( itemList );
            rDlg.setWindowTitle( "Largest files" );
            rDlg.exec();
        }
    }
    else
        QMessageBox::critical( this, "Largest files", "There are no files in listing");
}

QList<QTreeWidgetItem *> MainWindow::findMyFileItems( qlonglong _size ) const
{
    QList<QTreeWidgetItem *> retList;
    QTreeWidgetItemIterator it( ui->treeWidget );
    while (*it)
    {
        if ( (*it)->text(22) == "file" && !(*it)->text(23).isEmpty() )
        {
            bool ok;
            qlonglong num = (*it)->text(23).toLongLong( &ok, 10 );
            if ( ok && num == _size )
                retList.append( *it );
        }
        ++it;
    }
    return retList;
}

void MainWindow::on_actionLargest_folders_triggered()
{
    if ( ui->treeWidget->topLevelItemCount() > 0)
    {
        bool ok = false;
        QList<QTreeWidgetItem *> foldersList = getTopLevelFolders();
        if ( foldersList.size() > 0 )
        {
            int number = QInputDialog::getInt(this, tr("Please specify the number of items to display"),
                                          tr("Number:"), 5, 0, foldersList.count(), 1, &ok);

            if ( ok )
            {
                QList<qlonglong> foldersSizeList;
                QList<QTreeWidgetItem *> itemList;

                for ( int i = 0; i < foldersList.count(); i++ )
                {
                    qlonglong tempS = getFolderItemSize( foldersList.at(i) );
                    foldersList.at(i)->setText( 23, QString::number(tempS) );
                    if ( !foldersSizeList.contains(tempS) )
                        foldersSizeList << tempS;
                }

                // sorting
                qSort(foldersSizeList.begin(), foldersSizeList.end());

                for ( int i = 0; i < ( number > foldersSizeList.size() ? foldersSizeList.size() : number ); i++ )
                    itemList.append( findMyFolderItems( foldersSizeList.at(i) ) );

                reportDialog rDlg(this);
                rDlg.setData( itemList );
                rDlg.setWindowTitle( "Largest folders" );
                rDlg.exec();
            }
        }
        else
            QMessageBox::critical( this, "Largest folders", "There are no folders in listing");
    }
    else
        QMessageBox::critical( this, "Largest folders", "There are no folders in listing");
}

QList<QTreeWidgetItem *> MainWindow::getTopLevelFolders()
{
    QList<QTreeWidgetItem *> folders;
    if ( mySettings->rootFolderShow() || (ftpMode && dirMode) )
    {
        for ( int i = 0; i < ui->treeWidget->topLevelItemCount(); i++ )
        {
            for ( int j = 0; j < ui->treeWidget->topLevelItem(i)->childCount(); j++ )
            {
                if ( isItemFolder( ui->treeWidget->topLevelItem(i)->child(j) ) )
                    folders << ui->treeWidget->topLevelItem(i)->child(j);
            }
        }
    }
    else
    {
        for ( int i = 0; i < ui->treeWidget->topLevelItemCount(); i++ )
        {
            if ( isItemFolder( ui->treeWidget->topLevelItem( i ) ) )
                folders << ui->treeWidget->topLevelItem( i );
        }
    }

    return folders;
}

qlonglong MainWindow::getFolderItemSize( QTreeWidgetItem * item )
{
    qlonglong folderSize = 0;

    if ( item->childCount() > 0 )
    {
        for ( int i = 0; i < item->childCount(); i++ )
        {
            bool ok;
            if ( item->child(i)->text(22) == "file" )
                folderSize += item->child(i)->text(23).toLongLong( &ok, 10 );
            else
                folderSize += getFolderItemSize( item->child(i) );
        }
    }

    return folderSize;
}

QList<QTreeWidgetItem *> MainWindow::findMyFolderItems( qlonglong _size ) const
{
    QList<QTreeWidgetItem *> retList;
    if ( mySettings->rootFolderShow() || (ftpMode && dirMode) )
    {
        for ( int i = 0; i < ui->treeWidget->topLevelItemCount(); i++ )
        {
            for ( int j = 0; j < ui->treeWidget->topLevelItem(i)->childCount(); j++ )
            {
                if ( ui->treeWidget->topLevelItem(i)->child(j)->text(22) == "folder" &&
                     !ui->treeWidget->topLevelItem(i)->child(j)->text(23).isEmpty() )
                {
                    if ( ui->treeWidget->topLevelItem(i)->child(j)->text(23) == QString::number(_size) )
                        retList.append( ui->treeWidget->topLevelItem(i)->child(j) );
                }
            }
        }
    }
    else
    {
        for ( int i = 0; i < ui->treeWidget->topLevelItemCount(); i++ )
        {
            if ( ui->treeWidget->topLevelItem(i)->text(22) == "folder" &&
                 !ui->treeWidget->topLevelItem(i)->text(23).isEmpty() )
            {
                if ( ui->treeWidget->topLevelItem(i)->text(23) == QString::number(_size) )
                    retList.append( ui->treeWidget->topLevelItem(i) );
            }
        }
    }
    return retList;
}

// ------------------------- custom context menu functions ------------------------------
int MainWindow::selectionType()
{
    int res = 0, fCount = 0;

    QList<QTreeWidgetItem*> tList = ui->treeWidget->selectedItems();
    for ( int i = 0; i < tList.size(); i++ )
    {
        if ( !isItemFolder( tList.at(i) ) )
            fCount++;
        if ( tList.at(i)->text(30) == "ftp" )
            return 3;
    }

    if ( fCount == tList.size() )
        res = 1;
    else if ( fCount > 0 )
        res = -1;

    return res;
}

void MainWindow::on_treeWidget_customContextMenuRequested(QPoint pos)
{
    if ( ui->treeWidget->selectedItems().size() > 0 && ui->treeWidget->itemAt( pos ) )
    {
        if ( selectionType() == 0 )
        {
            if ( ui->treeWidget->selectedItems().size() == 1 )
                p_folderOpenAction->setEnabled( true );
            else
                p_folderOpenAction->setEnabled( false );
            p_folderExpandAction->setEnabled( true );
            p_folderCollapseAction->setEnabled( true );
            folderMenu->exec( QCursor::pos() );
        }
        if ( selectionType() == 1 )
            fileMenu->exec( QCursor::pos() );
    }
    else
    {
        p_folderOpenAction->setEnabled( false );
        p_folderExpandAction->setEnabled( false );
        p_folderCollapseAction->setEnabled( false );
        folderMenu->exec( QCursor::pos() );
    }
}

void MainWindow::p_folderOpenAction_triggered()
{
    if ( ui->treeWidget->selectedItems().size() == 1 )
        if ( !ui->treeWidget->selectedItems().at(0)->text(26).isEmpty() )
            QDesktopServices::openUrl(QUrl::fromLocalFile(QString( ui->treeWidget->selectedItems().at(0)->text(26) ) ) );
}

void MainWindow::p_folderExpandAction_triggered()
{
    if ( ui->treeWidget->selectedItems().size() == 1 )
    {
        ui->treeWidget->selectedItems().at(0)->setExpanded( true );
    }
}

void MainWindow::p_folderCollapseAction_triggered()
{
    if ( ui->treeWidget->selectedItems().size() == 1 )
    {
        ui->treeWidget->selectedItems().at(0)->setExpanded( false );
    }
}

void MainWindow::p_folderExpandAllAction_triggered()
{
    QTreeWidgetItemIterator it( ui->treeWidget, QTreeWidgetItemIterator::HasChildren );
    while (*it)
    {
        if ( !(*it)->isExpanded() )
            (*it)->setExpanded( true );
        ++it;
    }
}

void MainWindow::p_folderCollapseAllAction_triggered()
{
    QTreeWidgetItemIterator it( ui->treeWidget, QTreeWidgetItemIterator::HasChildren );
    while (*it)
    {
        if ( (*it)->isExpanded() )
            (*it)->setExpanded( false );
        ++it;
    }
}

void MainWindow::p_fileOpenAction_triggered()
{
    if ( ui->treeWidget->selectedItems().size() == 1 )
        if ( !ui->treeWidget->selectedItems().at(0)->text(26).isEmpty() )
            QDesktopServices::openUrl(QUrl::fromLocalFile(QString( ui->treeWidget->selectedItems().at(0)->text(26) ) ) );
}

void MainWindow::p_fileCopyAction_triggered()
{
    if ( ui->treeWidget->selectedItems().size() > 1 )
        QMessageBox::critical( this, "Error", "Cannot copy multiple items" );
    else if ( ui->treeWidget->selectedItems().size() == 1 )
    {
        if ( !isItemFolder( ui->treeWidget->selectedItems().at(0) ) )
        {
            QApplication::clipboard()->clear();

            QMimeData * md = new QMimeData();
            QUrl url1;
            url1.setPath( ui->treeWidget->selectedItems().at(0)->text(26) );
            if ( url1.isValid() )
            {
                QList<QUrl> list;
                list.append( url1 );
                md->setUrls( list );
                QApplication::clipboard()->setMimeData( md );
            }
        }
        else
            QMessageBox::critical( this, "Error", "Cannot copy folder" );
    }
}

void MainWindow::p_fileDeleteAction_triggered()
{
    if ( ui->treeWidget->selectedItems().size() > 0 )
    {
        switch( QMessageBox::warning( this, "Delete file",
                                      "Do you really want to delete these files from your computer?",
                                      "Yes",
                                      "No", 0, 0, 1 ) )
        {
        case 1:
            {
                return;
            }
        }

        QList<QTreeWidgetItem*> pList = ui->treeWidget->selectedItems();
        for ( int i = 0; i < pList.size(); i++ )
        {
            if ( QFile::remove( pList.at(i)->text(26) ) )
            {
                if ( pList.at(i)->parent() )
                    pList.at(i)->parent()->takeChild( pList.at(i)->parent()->indexOfChild( pList.at(i) ));
                else
                    ui->treeWidget->takeTopLevelItem( ui->treeWidget->indexOfTopLevelItem( pList.at(i) ) );
            }
            else
            {
                QMessageBox::critical( this, "Error", QString("Couldn't delete '%1'").arg( pList.at(i)->text(0)) );
                break;
            }
        }
    }
}

void MainWindow::applyFilters()
{
    QTreeWidgetItemIterator it( ui->treeWidget );
    while (*it)
    {
        if ( matchFilter(*it) )
            (*it)->setHidden( false );
        else
            (*it)->setHidden( true );
        ++it;
    }
}

bool MainWindow::matchFilter( QTreeWidgetItem * item )
{
    return matchAttributes(item) & matchType(item);
}

bool MainWindow::matchAttributes(QTreeWidgetItem *item )
{
    if ( ui->filterComboBox->currentIndex() == 0 ||
         item->text(28).contains( ui->filterComboBox->currentText(), Qt::CaseInsensitive ) )
        return true;

    return false;
}

bool MainWindow::matchType(QTreeWidgetItem *item )
{
    if ( isItemFolder(item) &&
         (ui->displayItemsCombo->currentIndex() == 2 || ui->displayItemsCombo->currentIndex() == 0 ))
            return true;
    if ( !isItemFolder(item) &&
         (ui->displayItemsCombo->currentIndex() == 1 || ui->displayItemsCombo->currentIndex() == 0 ))
            return true;
    return false;
}

void MainWindow::on_treeWidget_itemExpanded(QTreeWidgetItem* item)
{
    if (item->childCount() > 0 )
    {
        for ( int i = 0; i < ui->treeWidget->columnCount(); i++ )
            ui->treeWidget->resizeColumnToContents(i);
    }
}

void MainWindow::enableRefresh()
{
    ui->actionRefresh->setEnabled( true );
}

void MainWindow::on_filterComboBox_currentIndexChanged(QString )
{
    applyFilters();
}

void MainWindow::on_displayItemsCombo_currentIndexChanged(int )
{
    applyFilters();
}
